﻿// See https://aka.ms/new-console-template for more information

namespace Kestrel_Demo
{
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.StaticFiles;
    using Microsoft.Extensions.FileProviders;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using System;
    using System.IO;
    using System.Threading;

    
    public class Program
    {
        [DllImport("*")]
        static extern void SetIcsNativeaotActiveCode(byte[] activeCode);

        // LED 状态为类级别静态字段，便于在不同请求中访问
        private static bool ledState = false;

        // 占位：传感器、LED 的实现。编译为 NativeAOT 时，如果有真实硬件实现，请替换这些方法的内容。
        private static int ReadTemperatureSensor()
        {
            // TODO: 用真实传感器代码替换
            return Random.Shared.Next(0, 100);
        }

        private static int ReadHumiditySensor()
        {
            // TODO: 用真实传感器代码替换
            return Random.Shared.Next(0, 100);
        }

        private static bool ToggleLed()
        {
            // TODO: 用真实 GPIO 控制替换，并返回真实状态
            ledState = !ledState;
            return ledState;
        }

        // 显式声明依赖，防止 AOT 修剪
        [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(StaticFileMiddleware))]
        [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(StaticFileOptions))]
        [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(FileExtensionContentTypeProvider))]
        public static void Main(string[] args) 
        {
            var activeCode = new byte[] { 0x3B, 0xD9, 0xDD, 0xF5, 0x00, 0xCE, 0x42, 0x8D, 0x5D, 0xAA, 0xEA, 0x90, 0x81, 0xB8, 0xEE, 0x80, 0xAB, 0xCD, 0x78, 0x71, 0xA3, 0xB1, 0x97, 0x4F, 0x9C, 0x01, 0xCE, 0xE2, 0x58, 0x0A, 0x84, 0xB1, };

            //获取当前platform
            var url = "http://localhost:10086";
            var platform = RuntimeInformation.ProcessArchitecture;
            if (platform == Architecture.Arm)
            {
                SetIcsNativeaotActiveCode(activeCode);
                Directory.SetCurrentDirectory("/mnt/sd0/home");
                Console.WriteLine("set current directory to /mnt/sd0/home");
                url = "http://10.0.0.2:10086";
                Thread.Sleep(3000);
            }
            //关闭IPV6
            AppContext.SetSwitch("System.Net.Sockets.UseIPv6", true);

            var contentRoot = Directory.GetCurrentDirectory();
            var wwwroot = Path.Combine(contentRoot, "wwwroot");
            Console.WriteLine($"GetCurrentDirectory: {contentRoot}");


            // 构建Web主机
            var host = new WebHostBuilder()
                .UseContentRoot(contentRoot)
                .UseKestrel()
                .Configure(app =>
                {
                    // 配置默认文件选项
                    var defaultFilesOptions = new DefaultFilesOptions();

                    // 设置默认文件列表，优先级从高到低
                    defaultFilesOptions.DefaultFileNames.Clear();
                    defaultFilesOptions.DefaultFileNames.Add("index.html");
                    defaultFilesOptions.DefaultFileNames.Add("default.html");
                    defaultFilesOptions.DefaultFileNames.Add("default.htm");

                    // 使用默认文件中间件
                    app.UseDefaultFiles(defaultFilesOptions);

                    // 使用静态文件中间件，允许访问wwwroot目录下的静态文件
                    app.UseStaticFiles(new StaticFileOptions
                    {
                        FileProvider = new PhysicalFileProvider(
                            Path.Combine(contentRoot, "wwwroot")
                        ),
                        RequestPath = "", // 映射到根路径
                        OnPrepareResponse = ctx =>
                        {
                            // 如果响应是 text/*，确保包含 charset=utf-8（避免浏览器误解编码）
                            var resp = ctx.Context.Response;
                            var ct = resp.ContentType;
                            if (!string.IsNullOrEmpty(ct) &&
                                ct.StartsWith("text/", StringComparison.OrdinalIgnoreCase) &&
                                !ct.Contains("charset", StringComparison.OrdinalIgnoreCase))
                            {
                                resp.ContentType = ct + "; charset=utf-8";
                            }
                            else if (string.IsNullOrEmpty(ct))
                            {
                                // 兜底：对 .html 明确设置
                                var ext = Path.GetExtension(ctx.File.Name);
                                if (string.Equals(ext, ".html", StringComparison.OrdinalIgnoreCase))
                                {
                                    resp.ContentType = "text/html; charset=utf-8";
                                }
                            }
                        }
                    });

                    // 处理/api/hello路径
                    app.Map("/api/hello", m =>
                    {
                        m.Run(async context =>
                        {
                            // 明确设置动态响应的 Content-Type 与编码
                            context.Response.ContentType = "text/plain; charset=utf-8";

                            var name = context.Request.Query["name"];
                            var message = string.IsNullOrEmpty(name)
                                ? "Hello, World!"
                                : $"Hello, {name}!";

                            await context.Response.WriteAsync($"api/hello：{message}");
                        });
                    });

                    app.Map("/api/device/info", m =>
                    {
                        m.Run(async context =>
                        {
                            context.Response.ContentType = "application/json; charset=utf-8";
                            var info = new
                            {
                                uptime = $"{Environment.TickCount / 3600000}h {(Environment.TickCount % 3600000) / 60000}m",
                                memoryUsage = GC.GetTotalMemory(false) / 1024 / 1024, // MB
                                totalMemory = 64, // 64MB
                                cpuLoad = 1,
                                networkStatus = "Connected"
                            };
                            var json = System.Text.Json.JsonSerializer.Serialize(info);
                            await context.Response.WriteAsync(json);
                        });
                    });

                    app.Map("/api/led/toggle", m =>
                    {
                        m.Run(async context =>
                        {
                            // 仅接受 POST（前端使用 axios.post）
                            if (!string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase))
                            {
                                context.Response.StatusCode = StatusCodes.Status405MethodNotAllowed;
                                context.Response.ContentType = "text/plain; charset=utf-8";
                                await context.Response.WriteAsync("Method Not Allowed");
                                return;
                            }

                            bool newLedState = ToggleLed();
                            context.Response.ContentType = "application/json; charset=utf-8";
                            var result = System.Text.Json.JsonSerializer.Serialize(new { ledState = newLedState });
                            await context.Response.WriteAsync(result);
                        });
                    });

                    app.Map("/api/sensors", m =>
                    {
                        m.Run(async context =>
                        {
                            context.Response.ContentType = "application/json; charset=utf-8";
                            var result = System.Text.Json.JsonSerializer.Serialize(new
                            {
                                temperature = ReadTemperatureSensor(), // 你的传感器读取函数
                                humidity = ReadHumiditySensor(),
                            });
                            await context.Response.WriteAsync(result);
                        });
                    });

                    // 处理未匹配的路径
                    app.Run(async context =>
                    {
                        context.Response.StatusCode = StatusCodes.Status404NotFound;
                        context.Response.ContentType = "text/plain; charset=utf-8";
                        await context.Response.WriteAsync("404 - 资源未找到");
                    });
                })
                .UseUrls(url)
                .Build();
            
            host.Start();

            Console.WriteLine($"Kestrel Web,{url}");

            Thread.Sleep(Timeout.Infinite);
        }
    }
}





